// 自调用函数
// 第三个对象：游戏者
(function() {
    // 创建游戏对象
    var that; //记录游戏对象
    function Game(map) {
        this.food = new Food(); // this.food是Food的实例对象
        this.snake = new Snake(); //this.snake 是Snake的实例对象
        this.map = map;
        that = this;
    }

    // 开始游戏方法
    Game.prototype.start = function() {
        // 1、把蛇和食物对象渲染到地图上
        this.food.render(this.map);
        this.snake.render(this.map);

        // // 测试
        // this.snake.move();
        // this.snake.render(this.map);
        // this.snake.move();
        // this.snake.render(this.map);

        // 2、开始游戏的逻辑
        // 2.1 让蛇不停地移动起来
        runSnake();

        // 2.3 通过键盘控制蛇的移动方向
        bindKey();
    }

    // 2.1 让蛇不停地移动起来 私有函数，不让外界访问
    function runSnake() {
        var timerId = setInterval(function() {
            // 每200毫秒，蛇走一格
            // 在定时器的function中，this指向window，所以不能通过this.snake获取当前蛇
            // 通过实例调用获取Snake的方法
            // bug：如果调用方法时，忘记参数，将报错，snake.js中参数undefined
            this.snake.move(this.food, map);
            this.snake.render(this.map);

            // 2.2 当蛇头超过边界游戏结束
            // 先获取蛇头的坐标
            var headX = this.snake.body[0].x;
            var headY = this.snake.body[0].y;
            var maxX = this.map.offsetWidth / this.snake.width;
            var maxY = this.map.offsetHeight / this.snake.height;
            if (headX < 0 || headX >= maxX) {
                alert('game over');
                clearInterval(timerId);
            }
            if (headY < 0 || headY >= maxY) {
                alert('game over');
                clearInterval(timerId);
            }
        }.bind(that), 200)
    }

    // 2.3 通过键盘控制蛇的移动方向
    function bindKey() {
        // 注册键盘按下事件
        // 为何不用onkeydown方法注册：因为这个方法注册的事件只有一个事件函数，不方便添加其他功能
        // document.onkeydown=function(){};//方法一
        document.addEventListener('keydown', function(e) {
            // console.log(e.keyCode);
            // 37-left
            // 38-top
            // 39-right
            // 40-bottom
            switch (e.keyCode) {
                case 37:
                    this.snake.direction = 'left';
                    break;
                case 38:
                    this.snake.direction = 'top';
                    break;
                case 39:
                    this.snake.direction = 'right';
                    break;
                case 40:
                    this.snake.direction = 'bottom';
                    break;
            }
        }.bind(that), false)
    }
    // 事件函数调用bind(that)方法,是为了让事件函数内部的this指向Game构造函数里的that


    //  暴露构造函数给外部
    window.Game = Game;

})()

// 测试
// var map = document.getElementById('map');
// var game = new Game(map);
// game.start();